<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>this指向总结</title>
</head>

<body>
  <script>
    // ============================== this指向总结 ==============================
    // 普通函数
    // ============ 1.1 全局内调用 ============
    function fn() {
      console.log(this)  // window
    }
    fn()

    // ============ 1.2 对象内调用 ============
    const obj = {
      name: '佩奇',
      sayHi() {
        console.log(this) //obj
      }
    }

    // ============ 1.3 构造函数内this ============
    function Person() {
      this.name = 'lw'
      console.log(this)   //指向实例对象zs
    }
    const zs = new Person()  
  
    // ============ 1.4 事件处理函数中的this ============
    document.addEventListener('click', function () {
      console.log(this)  //指向事件源
    })

    // ============ 1.5 调用 call  apply  bind 可以改变this指向 ============
    const o = { name: '佩奇' }
    function fun() {
      console.log(this)  
    }
    fun.call(o)
    fun.apply(o)

    // 箭头函数 没有this，是沿用上一级作用域的this
    const obj2 = {
      name: '佩奇',
      sayHi: () => {
        console.log(this) // window
      }
    }


    //  区分: 普通函数、箭头函数、方法简写
    let info = {
      sayHi1: function () {
        console.log(this)  // info
      },
      // 对象方法简写
      sayHi2() {
        console.log(this)  // info
      },
      // 箭头函数 没有this指向上一层 window
      sayHi3: () => {
        console.log(this)  // window
      }
    }

    info.sayHi1()
    info.sayHi2()
    info.sayHi3()
  </script>
</body>

</html>